package me.chenjp.tracker.core.filter;

import com.alibaba.fastjson.JSON;
import me.chenjp.tracker.core.bean.State;
import me.chenjp.tracker.service.JwtService;
import me.chenjp.tracker.core.utils.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * @author: Chenjp
 * @description: 这个人很懒, 没有留下任何注释
 * @create: 2019-05-03 13:03
 */
public class JwtTokenAuthFilter extends OncePerRequestFilter {
    private static final Logger logger = LoggerFactory.getLogger(JwtTokenAuthFilter.class);
    private Set<Pattern> excludeUrl;

    @Resource
    private JwtService jwtService;

    public JwtTokenAuthFilter() {
    }

    public void setExcludeUrl(Set<Pattern> excludeUrl) {
        this.excludeUrl = excludeUrl;
    }

    private boolean isExclude(HttpServletRequest request) {
        String uri = request.getRequestURI();
        if (CollectionUtils.isEmpty(this.excludeUrl)) {
            return false;
        } else {
            boolean result = this.excludeUrl.parallelStream().anyMatch((s) -> {
                return s.matcher(uri).find();
            });
            // logger.debug("exclude request uri:{},result:{}", uri, result);
            return result;
        }
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (this.isExclude(request)) {
            filterChain.doFilter(request, response);
        } else {
            String authorizationHeader = request.getHeader("Authorization");
            if (StringUtils.hasText(authorizationHeader) && authorizationHeader.startsWith("Bearer ")) {
                String token = authorizationHeader.substring(7);

                try {
                    jwtService.verify(token);
                    filterChain.doFilter(request, response);
                } catch (Exception var9) {
                    logger.warn("Could not getFile claims,invalid token,IP:{},Cause:{}", HttpUtils.getRemoteIP(request), var9.getMessage());
                    this.convertMsgToJson(response, "Token is expired");
                }

            } else {
                logger.warn("did not find token in header,request:{},ip:{}", request.getRequestURL(), HttpUtils.getRemoteIP(request));
                this.convertMsgToJson(response, "Invalid token");
            }
        }
    }

    public void convertMsgToJson(HttpServletResponse response, String errMsg) throws IOException {
        State errorResponse = new State(HttpStatus.UNAUTHORIZED.value(), errMsg);
        response.setHeader("WWW-Authenticate", "xBasic realm=\"fake\"");
        response.setStatus(401);
        response.getWriter().print(JSON.toJSON(errorResponse));
    }
}
